import type { AutoRouterNode, ParsedAutoRouterOptions } from '../types'
import { writeFile } from 'node:fs/promises'
import path from 'node:path'
import {
  ELEGANT_ROUTER_TYPES_MODULE_NAME,
  NOT_FOUND_ROUTE_NAME,
  ROOT_ROUTE_NAME,
} from '../constants'
import { createPrefixCommentOfGenFile, ensureFile } from '../shared'

export async function generateImportsFile(nodes: AutoRouterNode[], options: ParsedAutoRouterOptions): Promise<void> {
  const { cwd, routerGeneratedDir } = options

  const importsPath = path.posix.join(cwd, routerGeneratedDir, 'imports.ts')

  await ensureFile(importsPath)

  const code = getImportsCode(nodes, options)

  await writeFile(importsPath, code)
}

export function getImportsCode(nodes: AutoRouterNode[], options: ParsedAutoRouterOptions): string {
  const { layouts } = options

  const preCode = createPrefixCommentOfGenFile()

  let importCode = `import type { RouteFileKey, RouteLayoutKey, RawRouteComponent, AutoRouterRoute } from "${ELEGANT_ROUTER_TYPES_MODULE_NAME}";\n`

  let exportLayoutCode = `\nexport const layouts: Record<RouteLayoutKey, RawRouteComponent> = {`

  layouts.forEach((layout) => {
    const { name, importName, importPath, isLazy } = layout

    if (isLazy) {
      exportLayoutCode += `\n  ${name}: () => import("${importPath}"),`
    }
    else {
      importCode += `import ${importName} from "${importPath}";\n`
      exportLayoutCode += `\n  ${name}: ${importName},`
    }
  })
  exportLayoutCode += '\n};\n'

  let exportCode = `export const views: Record<RouteFileKey, RawRouteComponent> = {`
  nodes
    .filter(node => !node.isBuiltin && !node.isReuse)
    .forEach((node) => {
      const { name, importName, importPath, isLazy } = node

      if (isLazy) {
        exportCode += `\n  ${name}: () => import("${importPath}"),`
      }
      else {
        importCode += `import ${importName} from "${importPath}";\n`
        exportCode += `\n  ${name}${name === importName ? '' : `: ${importName}`},`
      }
    })

  exportCode += '\n};\n'

  //  内置路由
  let builtinCode = ''
  nodes.filter(node => node.isBuiltin)
    .forEach((node) => {
      const { name, path, component, layout } = node
      if (ROOT_ROUTE_NAME === name) {
        builtinCode += `export const ROOT_ROUTE: AutoRouterRoute = {`
        builtinCode += `\n  name: '${name}',`
        builtinCode += `\n  path: '${path}',`
        builtinCode += `\n  redirect: '${options.rootRedirect}',`
        builtinCode += `\n  meta: {`
        builtinCode += `\n    title: '${name}',`
        builtinCode += `\n    hideInMenu: true`
        builtinCode += `\n  }\n};`
      }
      builtinCode += '\n'
      if (NOT_FOUND_ROUTE_NAME === name) {
        builtinCode += `export const NOT_FOUND_ROUTE: AutoRouterRoute = {`
        builtinCode += `\n  name: '${name}',`
        builtinCode += `\n  path: '${path}',`
        builtinCode += `\n  layout: '${layout}',`
        builtinCode += `\n  component: '${component}',`
        builtinCode += `\n  meta: {`
        builtinCode += `\n    title: '${name}',`
        builtinCode += `\n    hideInMenu: true`
        builtinCode += `\n  }\n};`
      }
    })

  // console.log(`${ preCode } \n\n${ importCode }${ exportLayoutCode } \n${ exportCode } `)
  return `${preCode} \n\n${importCode}${exportLayoutCode} \n${exportCode} \n${builtinCode} `
}
